"""
CSPBuilder plugin

Provides multiplier functionality

Copyright (c) 2008 Rune M. Friborg, runef@diku.dk.
See LICENSE.txt for licensing details (GPLv2).
"""

PLUGIN_NAME = "Multiplier"

import copy
from plugins.execute import *

class PluginMultiplier(PluginEXECUTION):

    def __init__(self, pluginManager):
        PluginEXECUTION.__init__(self, pluginManager, PLUGIN_NAME)

    def fixProcessTree(self, p):

        added_PROCESSLINKS = []
        added_CHANNELS = []
        added_CPOINTS = []

        if p.has_key('PROCESSLINKS'):
            for pl in p['PROCESSLINKS']:
                if pl.has_key('multiplier') and int(pl['multiplier']) > 1:
                    mul = int(pl['multiplier'])
                    del pl['multiplier']

                    pl_proc = pl['PROCESS']
                    original_name = pl['name']
                    # Copy process
                    for x in range(1,mul):
                        new = copy.deepcopy(pl)
                        # Modify processlink name
                        new['name'] = 'MUL'+str(x)+'_'+original_name
                        # Modify process instance name
                        pl_proc['name'] = new['name']
                        added_PROCESSLINKS.append(new)

                    # Copy channels and create cpoints
                    if p.has_key('CHANNELS') and pl_proc.has_key('CHANNELENDS'):
                        for c in p['CHANNELS']:
                            for end in pl_proc['CHANNELENDS']:
                                if (end['direction'] == 'out'):
                                    if c['outTarget'] == original_name + '.' + end['name']:

                                        #create cpoint
                                        cpoint = {'name':'MUL_'+original_name+'_'+c['name']}

                                        #Multiply channels
                                        for x in range(mul):
                                            new = copy.deepcopy(c)
                                            new['name'] = 'MUL'+str(x)+'_'+new['name']
                                            if (x == 0):                                            
                                                new['inTarget'] = cpoint['name']+'.'
                                            else:
                                                new['inTarget'] = cpoint['name']+'.'
                                                new['outTarget'] = 'MUL'+str(x)+'_'+ original_name + '.' + end['name']
                                            added_CHANNELS.append(new)

                                        c['outTarget'] = cpoint['name']+'.'

                                        added_CPOINTS.append(cpoint)
                                else:
                                    if c['inTarget'] == original_name + '.' + end['name']:

                                        #create cpoint
                                        cpoint = {'name':'MUL_'+original_name+'_'+c['name']}

                                        #Multiply channels
                                        for x in range(mul):
                                            new = copy.deepcopy(c)
                                            new['name'] = 'MUL'+str(x)+'_'+new['name']
                                            if (x == 0):                                            
                                                new['outTarget'] = cpoint['name']+'.'
                                            else:
                                                new['outTarget'] = cpoint['name']+'.'
                                                new['inTarget'] = 'MUL'+str(x)+'_'+ original_name + '.' + end['name']
                                            added_CHANNELS.append(new)

                                        c['inTarget'] = cpoint['name']+'.'

                                        added_CPOINTS.append(cpoint)



                self.fixProcessTree(pl['PROCESS'])    

        if (added_CPOINTS):
            if (not p.has_key('CPOINTS')):
                p['CPOINTS'] = []
            p['CPOINTS'].extend(added_CPOINTS)

        if (added_CHANNELS):
            p['CHANNELS'].extend(added_CHANNELS)    

        if (added_PROCESSLINKS):
            p['PROCESSLINKS'].extend(added_PROCESSLINKS)    

        return p



def load(pluginManager):

    p = PluginMultiplier(pluginManager)

    p.addCSPTreeProcessing(p.fixProcessTree)

    pluginManager.addPlugin(p)
